"""
PromptTemplate 获取实例

两种特殊结构

给变量赋值的两种方式 format()/invoke()

结合大模型使用
"""
import os

import dotenv
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI


# 创建实例方式1，使用构造方法
def fun_1():
    #创建实例
    prompt_template = PromptTemplate(
        template= "你是一个{role} , 你的名字叫{name}"
        , input_variables=["role" , "name"]
    )

    #给实例变量赋值，使用format()方式
    prompt_1 = prompt_template.format(role="程序员", name="小王")
    prompt_2 = prompt_template.format(role="建筑师", name="小李")
    print(prompt_1)
    print(prompt_2)

#fun_1()

# 创建实例方式2 使用from_template() , 推荐
def fun_2():
    prompt_template = PromptTemplate.from_template(template="你是一个{role} , 你的名字叫{name}")
    # 给实例变量赋值，使用format()方式
    prompt_1 = prompt_template.format(role="程序员", name="小王")
    prompt_2 = prompt_template.format(role="建筑师", name="小李")
    print(prompt_1)
    print(prompt_2)

#fun_2()

#部分提示词模板 , 方式1
def fun_3():
    prompt_template = PromptTemplate.from_template(
        template="你的名字是{name}，来自{country}，职业是{role}"
        , partial_variables={"country": "中国"}
    )
    # 给实例变量赋值，使用format()方式
    prompt_1 = prompt_template.format(role="程序员", name="小王")
    prompt_2 = prompt_template.format(role="建筑师", name="小李")
    print(prompt_1)
    print(prompt_2)

#fun_3()


#部分提示词模板 , 方式2
def fun_4():
    prompt_template = PromptTemplate.from_template(
        template="你的名字是{name}，来自{country}，职业是{role}"
        , partial_variables={"country": "中国"}
    )

    new_template = prompt_template.partial(role="运动员") #partial不会对prompt_template产生操作，只返回一个新的prompt_template
    prompt_1 = new_template.format(name="小王")
    print(prompt_1)

#fun_4()

#使用invoke(),推荐
def fun_5():
    prompt_template = PromptTemplate.from_template(template="你是一个{role} , 你的名字叫{name}")
    # 给实例变量赋值，使用format()方式
    prompt_1 = prompt_template.invoke(input={"role": "程序员", "name": "小王"})
    prompt_2 = prompt_template.invoke(input={"role": "建筑师", "name": "小李"})
    print(prompt_1)
    print(prompt_2)

#fun_5()

#使用提示词模板调用大模型
def fun_6():
    # 加载配置文件
    dotenv.load_dotenv()

    # 调用会话模型，这里使用阿里百炼平台里的千问3
    chat_model = ChatOpenAI(
        model=os.getenv("MODEL_NAME")
        , base_url=os.getenv("BASE_URL")
        , api_key=os.getenv("API_KEY")
        , temperature=0.8  # 精确度
        , max_tokens=1024  # 回答长度
        , streaming=True  # 是否流式返回
    )

    # 创建提示词模板
    prompt_template = PromptTemplate.from_template(template="你是一个{role} , 你的名字叫{name},请你介绍下PYTHON")
    # 给模板实例变量赋值
    prompt = prompt_template.invoke(input={"role": "程序员", "name": "小王"})
    # 开始流失模式
    for chunk in chat_model.stream(prompt.to_string()):
        print(chunk.content, end="", flush=True)  # 输出流式数据 , end=""的作用是输出不换行 , flush=True作用是输出立即刷新

fun_6()